<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { Graph } from '@antv/g6'
import { message } from 'ant-design-vue'
import { ReloadOutlined } from '@ant-design/icons-vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart } from 'echarts/charts'
import { TitleComponent, TooltipComponent, LegendComponent, GridComponent, DataZoomComponent } from 'echarts/components'
import SimpleTopology from '@/components/cluster/SimpleTopology.vue'
import Legend from '@/components/cluster/Legend.vue'
import LatencyModalContent from '@/components/cluster/LatencyModalContent.vue'
import InfoActions from '@/components/cluster/InfoActions.vue'

// 注册 ECharts 组件
use([
  CanvasRenderer,
  LineChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  DataZoomComponent
])

interface NodeData {
  id: string
  name: string
  status: string
  cpu: number
  memory: number
  ip: string
  role: string
}

interface EdgeData {
  id: string
  source: string
  target: string
  latency?: {
    forward: number  // node1 -> node2
    backward: number // node2 -> node1
  }
}

// 响应式数据
const containerRef = ref<HTMLDivElement>()
const graph = ref<Graph | null>(null)
const loading = ref(false)
const useSimpleVersion = ref(false) // 是否使用简单版本
const selectedNodeId = ref<string | null>(null) // 当前选中的节点

// 模态框相关
const modalVisible = ref(false)
const latencyChartOptions = ref({})
const selectedEdge = ref<EdgeData | null>(null)

// 全局变量
const navStore = useNavStore();

// 简化的模拟数据 - 1个master + 3个worker
// const mockNodes: NodeData[] = [
//   { id: 'master-1', name: 'Master-1', status: 'Ready', cpu: 75, memory: 65, ip: '192.168.1.10', role: 'master' },
//   { id: 'worker-1', name: 'Worker-1', status: 'Ready', cpu: 45, memory: 70, ip: '192.168.1.20', role: 'worker' },
//   { id: 'worker-2', name: 'Worker-2', status: 'Ready', cpu: 60, memory: 55, ip: '192.168.1.21', role: 'worker' },
//   { id: 'worker-3', name: 'Worker-3', status: 'NotReady', cpu: 0, memory: 0, ip: '192.168.1.22', role: 'worker' },
// ]

// 修正 ref 变量的声明
const nodes = ref<NodeData[]>([]);

// 生成完全图的边 - 任意两个节点都相连
const generateCompleteGraphEdges = (): EdgeData[] => {
  const edges: EdgeData[] = []
  // 使用 nodes.value 正确访问响应式数据
  for (let i = 0; i < nodes.value.length; i++) {
    for (let j = i + 1; j < nodes.value.length; j++) {
      edges.push({
        id: `edge-${nodes.value[i].id}-${nodes.value[j].id}`,
        source: nodes.value[i].id,
        target: nodes.value[j].id
      })
    }
  }
  return edges
}
const edges = ref<EdgeData[]>([])

// 获取与指定节点相连的所有边
const getConnectedEdges = (nodeId: string): EdgeData[] => {
  return edges.value.filter(edge => edge.source === nodeId || edge.target === nodeId)
}

// 自动计算节点布局算法
const calculateNodeLayout = (nodes: NodeData[], containerWidth: number, containerHeight: number) => {
  // 分离control-plane节点和worker节点
  const controlPlaneNodes = nodes.filter(node => node.role === 'control-plane')
  const workerNodes = nodes.filter(node => node.role !== 'control-plane')

  const positions: Record<string, { x: number; y: number }> = {}

  // 布局参数
  const topMargin = containerHeight * 0.15  // 顶部边距
  const bottomMargin = containerHeight * 0.15  // 底部边距
  const sideMargin = containerWidth * 0.1  // 左右边距
  const availableWidth = containerWidth - 2 * sideMargin
  const availableHeight = containerHeight - topMargin - bottomMargin

  // 第一排：control-plane节点
  if (controlPlaneNodes.length > 0) {
    const firstRowY = topMargin + availableHeight * 0.25  // 第一排位置（上1/4处）

    if (controlPlaneNodes.length === 1) {
      // 单个control-plane节点居中
      positions[controlPlaneNodes[0].id] = {
        x: containerWidth / 2,
        y: firstRowY
      }
    } else {
      // 多个control-plane节点等间距排列
      const spacing = availableWidth / (controlPlaneNodes.length + 1)
      controlPlaneNodes.forEach((node, index) => {
        positions[node.id] = {
          x: sideMargin + spacing * (index + 1),
          y: firstRowY
        }
      })
    }
  }

  // 第二排：worker节点
  if (workerNodes.length > 0) {
    const secondRowY = topMargin + availableHeight * 0.75  // 第二排位置（下3/4处）

    if (workerNodes.length === 1) {
      // 单个worker节点居中
      positions[workerNodes[0].id] = {
        x: containerWidth / 2,
        y: secondRowY
      }
    } else {
      // 多个worker节点等间距排列
      const spacing = availableWidth / (workerNodes.length + 1)
      workerNodes.forEach((node, index) => {
        positions[node.id] = {
          x: sideMargin + spacing * (index + 1),
          y: secondRowY
        }
      })
    }
  }

  return positions
}

// 简化的初始化图
import G6 from '@antv/g6'
import { GetClusterNodes, GetNodeNetworkLatency } from "@/api/cluster";
import { useNavStore } from "@/store/nav.ts";

const initGraph = async () => {
  if (!containerRef.value) return

  loading.value = true

  try {
    // 如果已有实例，先销毁
    if (graph.value) {
      graph.value.destroy()
      graph.value = null
    }

    const width = containerRef.value.offsetWidth
    const height = containerRef.value.offsetHeight

    if (width < 100 || height < 100) {
      console.warn('容器尺寸过小，使用简化版本')
      useSimpleVersion.value = true
      return
    }

    // 使用自动布局算法计算节点位置
    const nodePositions = calculateNodeLayout(nodes.value, width, height)

    // 构造图数据 - 预先创建所有边但隐藏它们
    const data = {
      nodes: nodes.value.map(node => {
        const pos = nodePositions[node.id] || { x: width / 2, y: height / 2 }
        return {
          id: node.id,
          label: node.name,
          x: pos.x,
          y: pos.y,
          style: {
            fill: node.role === 'control-plane'
                ? (node.status === 'Ready' ? '#52c41a' : '#ff4d4f')
                : (node.status === 'Ready' ? '#1890ff' : '#ff4d4f'),
            stroke: node.role === 'control-plane' ? '#1890ff' : '#52c41a',
            lineWidth: 2
          }
        }
      }),
      // 预先创建所有边，但通过样式隐藏它们
      edges: edges.value.map(edge => ({
        id: edge.id,
        source: edge.source,
        target: edge.target,
        style: {
          stroke: '#1890ff',
          lineWidth: 3,
          strokeOpacity: 0.8,
          endArrow: false,
          // 初始状态下隐藏所有边
          opacity: 0,
        }
      }))
    }

    // 初始化图 (v4)
    graph.value = new G6.Graph({
      container: containerRef.value,
      width,
      height,
      defaultNode: {
        size: 50, // 增大节点尺寸
        labelCfg: {
          position: 'bottom',
          style: { fontSize: 14, fontWeight: 'bold' }
        }
      },
      defaultEdge: {
        type: 'line',
        style: {
          stroke: '#1890ff',
          lineWidth: 3,
          strokeOpacity: 0.8,
          endArrow: false
        }
      },
      nodeStateStyles: {
        selected: {
          stroke: '#faad14',
          lineWidth: 4,
          shadowColor: '#faad14',
          shadowBlur: 10
        },
        hover: {
          stroke: '#722ed1',
          lineWidth: 3,
          fillOpacity: 0.8
        }
      },
      edgeStateStyles: {
        hover: {
          stroke: '#722ed1',
          lineWidth: 4,
          strokeOpacity: 1,
          shadowColor: '#722ed1',
          shadowBlur: 8
        },
        selected: {
          stroke: '#52c41a',
          lineWidth: 4,
          strokeOpacity: 1
        }
      },
      modes: {
        default: ['zoom-canvas', 'drag-canvas', 'drag-node']
      }
    })

    // v4 加载数据
    graph.value.data(data)
    graph.value.render()

    // 初始化后隐藏所有边
    hideAllEdges()

    // 节点点击事件 - 显示/隐藏连接的边
    graph.value.on('node:click', evt => {
      if (!evt.item) return
      const nodeModel = evt.item.getModel()
      const nodeId = nodeModel.id as string

      // 清除所有节点的选中状态
      graph.value?.getNodes().forEach(node => {
        graph.value?.clearItemStates(node, ['selected'])
      })

      // 先隐藏所有边
      hideAllEdges()

      if (selectedNodeId.value === nodeId) {
        // 如果点击的是已选中的节点，则取消选中
        selectedNodeId.value = null
      } else {
        // 选中新节点并显示其连接的边
        selectedNodeId.value = nodeId
        graph.value?.setItemState(evt.item, 'selected', true)
        // 显示该节点连接的边
        showEdgesForSelectedNode(nodeId)
      }
    })

    // 边的点击事件
    graph.value.on('edge:click', evt => {
      if (!evt.item) return
      const edgeModel = evt.item.getModel()
      const edge = edges.value.find(e => e.id === edgeModel.id)
      if (edge) {
        // 清除之前选中的边的状态
        graph.value?.getEdges().forEach(e => {
          graph.value?.clearItemStates(e, ['selected'])
        })
        // 设置当前边为选中状态
        graph.value?.setItemState(evt.item, 'selected', true)
        showLatencyModal(edge)
      }
    })

    useSimpleVersion.value = false
  } catch (error) {
    console.error('G6 初始化失败，使用简化版本:', error)
    message.warning('使用简化版拓扑图')
    useSimpleVersion.value = true
  } finally {
    loading.value = false
  }
}

// 隐藏所有边
const hideAllEdges = () => {
  if (!graph.value) return

  const currentEdges = graph.value.getEdges()
  currentEdges.forEach(edge => {
    edge.hide()
  })
}

// 为选中节点显示连接的边
const showEdgesForSelectedNode = (nodeId: string) => {
  if (!graph.value) return

  // 获取与选中节点相连的边ID
  const connectedEdgeIds = getConnectedEdges(nodeId).map(edge => edge.id)

  // 显示相关的边
  const allEdges = graph.value.getEdges()
  allEdges.forEach(edge => {
    const edgeModel = edge.getModel()
    if (connectedEdgeIds.includes(edgeModel.id as string)) {
      edge.show()
    }
  })
}

// 显示指定节点的连接边（保留兼容性，内部调用新方法）
const showEdgesForNode = (nodeId: string | null) => {
  if (!graph.value) return

  if (nodeId === null) {
    hideAllEdges()
  } else {
    hideAllEdges()
    showEdgesForSelectedNode(nodeId)
  }
}

// 计算延迟数据的统计值
const calculateLatencyStats = (latencyData: number[]) => {
  if (!latencyData || latencyData.length === 0) {
    return { max: 0, min: 0, avg: 0 }
  }

  const validData = latencyData.filter(value => value != null && !isNaN(value))
  if (validData.length === 0) {
    return { max: 0, min: 0, avg: 0 }
  }

  const max = Math.max(...validData)
  const min = Math.min(...validData)
  const avg = validData.reduce((sum, value) => sum + value, 0) / validData.length

  return { max, min, avg }
}

// 添加统计数据的响应式变量
const forwardLatencyStats = ref({ max: 0, min: 0, avg: 0 })
const backwardLatencyStats = ref({ max: 0, min: 0, avg: 0 })

// 添加时间间隔相关变量
const timeRangeOptions = [
  { label: '过去5分钟', value: 5, unit: 'minutes' },
  { label: '过去15分钟', value: 15, unit: 'minutes' },
  { label: '过去半小时', value: 30, unit: 'minutes' },
  { label: '过去1小时', value: 1, unit: 'hours' },
  { label: '过去2小时', value: 2, unit: 'hours' }
]

const selectedTimeRange = ref(15) // 默认15分钟
const loadingLatencyData = ref(false) // 加载延迟数据的状态

// 修改计算时间范围的函数，支持不同单位
const calculateTimeRange = (value: number, unit: string = 'minutes') => {
  const endTime = new Date()
  let milliseconds = 0

  switch (unit) {
    case 'minutes':
      milliseconds = value * 60 * 1000
      break
    case 'hours':
      milliseconds = value * 60 * 60 * 1000
      break
    default:
      milliseconds = value * 60 * 1000 // 默认按分钟处理
  }

  const startTime = new Date(endTime.getTime() - milliseconds)
  return {
    startTime: startTime.toISOString(),
    endTime: endTime.toISOString()
  }
}

// 获取延迟数据的通用函数
const fetchLatencyData = async (edge: EdgeData, timeRangeValue: number) => {
  loadingLatencyData.value = true

  try {
    // 根据选中的时间范围获取对应的单位信息
    const selectedOption = timeRangeOptions.find(option => option.value === timeRangeValue)
    const unit = selectedOption?.unit || 'minutes'

    const { startTime, endTime } = calculateTimeRange(timeRangeValue, unit)

    // 调用API获取延迟数据
    const { data } = await GetNodeNetworkLatency(
      navStore.currentClusterId,
      edge.source,
      edge.target,
      startTime,
      endTime
    )

    // 处理API返回的数据
    let timestamps: Date[] = []
    let forwardLatency: number[] = []
    let backwardLatency: number[] = []

    if (data && data.node_latency_to_others) {
      timestamps = data.timestamp_list.map((item: string) => {
        return new Date(Date.parse(item))
      })
      forwardLatency = data.node_latency_to_others[`${edge.source}-${edge.target}`]?.map((item: any) => parseFloat(item.latency || 0)) || []
      backwardLatency = data.node_latency_to_others[`${edge.target}-${edge.source}`]?.map((item: any) => parseFloat(item.latency || 0)) || []
    } else {
      // 如果API没有返回数据，使用模拟数据作为fallback
      console.warn('API未返回延迟数据，使用模拟数据')
      const now = new Date()
      // 根据时间范围和单位计算数据点数量
      const totalMinutes = unit === 'hours' ? timeRangeValue * 60 : timeRangeValue
      const dataPoints = Math.max(Math.min(totalMinutes, 60), 5) // 最少5个点，最多60个点

      timestamps = Array.from({ length: dataPoints }, (_, i) => {
        const intervalMs = (unit === 'hours' ? timeRangeValue * 60 * 60 * 1000 : timeRangeValue * 60 * 1000) / dataPoints
        return new Date(now.getTime() - (dataPoints - 1 - i) * intervalMs)
      })
      forwardLatency = Array.from({ length: dataPoints }, () => Math.random() * 20 + 10)
      backwardLatency = Array.from({ length: dataPoints }, () => Math.random() * 25 + 8)
    }

    return { timestamps, forwardLatency, backwardLatency }
  } finally {
    loadingLatencyData.value = false
  }
}

// 更新图表数据
const updateChartData = (edge: EdgeData, timestamps: Date[], forwardLatency: number[], backwardLatency: number[]) => {
  // 计算统计数据
  forwardLatencyStats.value = calculateLatencyStats(forwardLatency)
  backwardLatencyStats.value = calculateLatencyStats(backwardLatency)

  // 计算实际的时间范围（毫秒）
  const timeRange = timestamps.length > 0 ?
    timestamps[timestamps.length - 1].getTime() - timestamps[0].getTime() :
    (() => {
      // 根据选中的时间范围计算毫秒数
      const selectedOption = timeRangeOptions.find(option => option.value === selectedTimeRange.value)
      const unit = selectedOption?.unit || 'minutes'
      return unit === 'hours' ? selectedTimeRange.value * 60 * 60 * 1000 : selectedTimeRange.value * 60 * 1000
    })()

  // 根据时间范围自动选择合适的时间格式
  const getTimeFormatter = (range: number) => {
    if (range <= 60 * 60 * 1000) { // 1小时内
      return (value: any) => {
        const date = new Date(value)
        return date.toLocaleTimeString('zh-CN', {
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit'
        })
      }
    } else if (range <= 24 * 60 * 60 * 1000) { // 24小时内
      return (value: any) => {
        const date = new Date(value)
        return date.toLocaleTimeString('zh-CN', {
          hour: '2-digit',
          minute: '2-digit'
        })
      }
    } else { // 超过24小时
      return (value: any) => {
        const date = new Date(value)
        return date.toLocaleDateString('zh-CN', {
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit'
        })
      }
    }
  }

  // 配置 ECharts 选项
  latencyChartOptions.value = {
    title: {
      text: `网络延迟: ${edge.source} ↔ ${edge.target}`,
      left: 'center',
      textStyle: {
        fontSize: 16,
        fontWeight: 'bold'
      }
    },
    tooltip: {
      trigger: 'axis',
      formatter: function(params: any) {
        if (!params || params.length === 0) return ''

        const time = new Date(params[0].axisValue)
        const timeStr = time.toLocaleString('zh-CN', {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit'
        })

        let result = `<div style="font-weight: bold; margin-bottom: 5px;">${timeStr}</div>`
        params.forEach((param: any) => {
          const value = Array.isArray(param.value) ? param.value[1] : param.value
          const numValue = typeof value === 'number' ? value : parseFloat(value) || 0

          result += `<div style="color: ${param.color}; margin: 2px 0;">
            <span style="display: inline-block; width: 10px; height: 10px; background: ${param.color}; border-radius: 50%; margin-right: 5px;"></span>
            ${param.seriesName}: ${numValue.toFixed(2)} ms
          </div>`
        })
        return result
      }
    },
    legend: {
      data: [`${edge.source} → ${edge.target}`, `${edge.target} → ${edge.source}`],
      top: 35,
      left: 'center'
    },
    grid: {
      left: '8%',
      right: '4%',
      bottom: '15%',
      top: '20%',
      containLabel: true
    },
    xAxis: {
      type: 'time',
      boundaryGap: false,
      axisLabel: {
        formatter: getTimeFormatter(timeRange),
        rotate: timeRange > 60 * 60 * 1000 ? 45 : 0,
        fontSize: 11,
        margin: 8
      },
      axisLine: {
        lineStyle: { color: '#d9d9d9' }
      },
      axisTick: {
        lineStyle: { color: '#d9d9d9' }
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: '#f0f0f0',
          type: 'dashed'
        }
      },
      name: '时间',
      nameLocation: 'middle',
      nameGap: 35,
      nameTextStyle: {
        fontSize: 12,
        color: '#666'
      }
    },
    yAxis: {
      type: 'value',
      name: '延迟 (ms)',
      nameRotate: 90,
      nameLocation: 'middle',
      nameGap: 40,
      nameTextStyle: {
        fontSize: 12,
        color: '#666'
      },
      axisLabel: {
        formatter: '{value} ms',
        fontSize: 11
      },
      axisLine: {
        lineStyle: { color: '#d9d9d9' }
      },
      axisTick: {
        lineStyle: { color: '#d9d9d9' }
      },
      splitLine: {
        lineStyle: {
          color: '#f0f0f0',
          type: 'dashed'
        }
      },
      min: function(value: any) {
        return Math.max(0, value.min - 2)
      }
    },
    series: [
      {
        name: `${edge.source} → ${edge.target}`,
        type: 'line',
        data: timestamps.map((time, index) => [time.getTime(), forwardLatency[index] || 0]),
        smooth: true,
        itemStyle: { color: '#1890ff' },
        lineStyle: { width: 2 },
        symbol: 'circle',
        symbolSize: 4,
        emphasis: {
          focus: 'series'
        },
        markPoint: {
          data: [
            { type: 'max', name: '最大值' },
            { type: 'min', name: '最小值' }
          ]
        }
      },
      {
        name: `${edge.target} → ${edge.source}`,
        type: 'line',
        data: timestamps.map((time, index) => [time.getTime(), backwardLatency[index] || 0]),
        smooth: true,
        itemStyle: { color: '#52c41a' },
        lineStyle: { width: 2 },
        symbol: 'circle',
        symbolSize: 4,
        emphasis: {
          focus: 'series'
        },
        markPoint: {
          data: [
            { type: 'max', name: '最大值' },
            { type: 'min', name: '最小值' }
          ]
        }
      }
    ],
    dataZoom: [
      {
        type: 'inside',
        start: 0,
        end: 100,
        zoomOnMouseWheel: true,
        moveOnMouseMove: true
      },
      {
        type: 'slider',
        start: 0,
        end: 100,
        height: 30,
        bottom: 20,
        handleStyle: {
          color: '#1890ff'
        },
        dataBackground: {
          areaStyle: {
            color: '#f0f0f0'
          },
          lineStyle: {
            color: '#d9d9d9'
          }
        },
        selectedDataBackground: {
          areaStyle: {
            color: '#bae7ff'
          },
          lineStyle: {
            color: '#1890ff'
          }
        }
      }
    ],
    animation: true,
    animationDuration: 1000,
    animationEasing: 'cubicOut'
  }
}

// 时间范围改变时的处理函数
const handleTimeRangeChange = async (newTimeRange: number) => {
  if (!selectedEdge.value) return

  selectedTimeRange.value = newTimeRange

  try {
    const { timestamps, forwardLatency, backwardLatency } = await fetchLatencyData(selectedEdge.value, newTimeRange)
    updateChartData(selectedEdge.value, timestamps, forwardLatency, backwardLatency)
  } catch (error) {
    console.error('Failed to update latency data:', error)
    message.error('更新延迟数据失败')
  }
}

// 修改显示延迟模态框函数
const showLatencyModal = async (edge: EdgeData) => {
  try {
    selectedEdge.value = edge

    // 立即显示模态框并设置loading状态
    loadingLatencyData.value = true
    modalVisible.value = true

    // 显示初始的空图表
    latencyChartOptions.value = {
      title: {
        text: `网络延迟: ${edge.source} ↔ ${edge.target}`,
        left: 'center',
        textStyle: {
          fontSize: 16,
          fontWeight: 'bold'
        }
      },
      xAxis: { type: 'time' },
      yAxis: { type: 'value', name: '延迟 (ms)' },
      series: []
    }

    // 重置为默认时间范围
    selectedTimeRange.value = 15

    // 获取数据
    const { timestamps, forwardLatency, backwardLatency } = await fetchLatencyData(edge, selectedTimeRange.value)

    // 更新图表
    updateChartData(edge, timestamps, forwardLatency, backwardLatency)

  } catch (error) {
    console.error('Failed to load latency data:', error)
    message.error('加载延迟数据失败')

    // 重置统计数据
    forwardLatencyStats.value = { max: 0, min: 0, avg: 0 }
    backwardLatencyStats.value = { max: 0, min: 0, avg: 0 }

    // 发生错误时显示错误图表
    latencyChartOptions.value = {
      title: {
        text: `网络延迟: ${edge.source} ↔ ${edge.target} (数据加载失败)`,
        left: 'center'
      },
      xAxis: { type: 'time' },
      yAxis: { type: 'value', name: '延迟 (ms)' },
      series: []
    }
  } finally {
    loadingLatencyData.value = false
  }
}

// 关闭模态框并清除选中状态
const closeModal = () => {
  modalVisible.value = false
  // 清除所有边的选中状态
  if (graph.value) {
    graph.value.getEdges().forEach(edge => {
      graph.value?.clearItemStates(edge, ['selected'])
    })
  }
  selectedEdge.value = null
  // 重置统计数据和时间范围
  forwardLatencyStats.value = { max: 0, min: 0, avg: 0 }
  backwardLatencyStats.value = { max: 0, min: 0, avg: 0 }
  selectedTimeRange.value = 15
  loadingLatencyData.value = false
}

// 处理窗口大小变化
const handleResize = () => {
  if (graph.value && containerRef.value) {
    const width = containerRef.value.offsetWidth
    const height = containerRef.value.offsetHeight

    // G6 v4 使用 changeSize 方法而不是 resize
    graph.value.changeSize(width, height)
    graph.value.fitView()
  }
}

// 刷新拓扑图
const refreshTopology = () => {
  initGraph()
}

// 恢复初始状态 - 清除所有选中状态和隐藏所有边
const resetToInitialState = () => {
  if (graph.value) {
    // 清除所有节点的选中状态
    graph.value.getNodes().forEach(node => {
      graph.value?.clearItemStates(node, ['selected'])
    })
    // 清除所有边的选中状态
    graph.value.getEdges().forEach(edge => {
      graph.value?.clearItemStates(edge, ['selected'])
    })
    // 重置选中的节点ID
    selectedNodeId.value = null
    // 隐藏所有边
    hideAllEdges()
  }
}

const loadNodes = async () => {
  const {data} = await GetClusterNodes(navStore.currentClusterId);
  console.log('节点数据', data);
  nodes.value = data.map(node => ({
    id: node.name,
    name: node.name,
    status: node.status,
    ip: node.ip,
    role: node.role  // 确保这里正确映射role字段
  }));
}

const loadEdges = async () => {
  let e = generateCompleteGraphEdges();
  edges.value = e;
}

// 生命周期
onMounted(async () => {
  await loadNodes();
  await loadEdges();
  await nextTick();
  await initGraph();
  window.addEventListener('resize', handleResize);
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  if (graph.value) {
    graph.value.destroy()
  }
})
</script>

<template>
  <div class="scheduling-view">
    <!-- 头部工具栏 -->
    <div class="header-toolbar">
      <div class="toolbar-left">
        <h2>Kubernetes 集群节点拓扑</h2>
        <p class="description">
          完全图展示：点击任意节点查看其网络连接，点击连接线查看延迟详情
        </p>
      </div>
      <div class="toolbar-right">
        <a-button
          type="default"
          :disabled="!selectedNodeId"
          @click="resetToInitialState"
          style="margin-right: 12px;"
        >
          <template #icon>
            <ReloadOutlined />
          </template>
          恢复
        </a-button>
        <a-button type="primary" :loading="loading" @click="refreshTopology">
          <template #icon>
            <ReloadOutlined/>
          </template>
          刷新拓扑
        </a-button>
      </div>
    </div>

    <!-- 拓扑图容器 -->
    <div class="topology-container">
      <a-spin :spinning="loading" tip="加载拓扑图中...">
        <!-- 如果G6加载失败，使用简单的SVG版本 -->
        <div v-if="useSimpleVersion" class="simple-topology-wrapper">
          <SimpleTopology/>
        </div>

        <!-- G6 图容器 -->
        <div
            v-else
            ref="containerRef"
            class="graph-container"
            :style="{ height: '400px' }"
        />

      </a-spin>

      <!-- 操作提示 -->
      <div class="operation-tips" v-if="!useSimpleVersion">
        <div class="tip-item">
          <span class="tip-icon">👆</span>
          <span>点击节点显示连接</span>
        </div>
        <div class="tip-item">
          <span class="tip-icon">🖱️</span>
          <span>拖拽画布移动视图</span>
        </div>
        <div class="tip-item">
          <span class="tip-icon">🔍</span>
          <span>滚轮缩放视图</span>
        </div>
        <div class="tip-item">
          <span class="tip-icon">🔗</span>
          <span>点击连接线查看延迟</span>
        </div>
        <div class="tip-item">
          <span class="tip-icon">🔄</span>
          <span>点击恢复按钮清除选中</span>
        </div>
      </div>

      <!-- 当前选中节点信息 -->
      <div class="selected-node-info" v-if="selectedNodeId && !useSimpleVersion">
        <div class="info-header">
          <span>当前选中: {{ nodes.find(n => n.id === selectedNodeId)?.name }}</span>
        </div>
        <div class="info-details">
          连接数: {{ getConnectedEdges(selectedNodeId).length }}
        </div>
        <InfoActions :onReset="resetToInitialState" />
      </div>
    </div>

    <!-- 节点状态图例 -->
    <Legend />

    <!-- 网络延迟模态框 -->
    <a-modal
      v-model:open="modalVisible"
      :title="`网络延迟分析 - ${selectedEdge?.source} ↔ ${selectedEdge?.target}`"
      width="900px"
      :footer="null"
      :destroyOnClose="true"
      @cancel="closeModal"
    >
      <a-spin :spinning="loadingLatencyData" tip="正在加载延迟数据...">
        <LatencyModalContent
          :selectedEdge="selectedEdge"
          :forwardLatencyStats="forwardLatencyStats"
          :backwardLatencyStats="backwardLatencyStats"
          :selectedTimeRange="selectedTimeRange"
          :timeRangeOptions="timeRangeOptions"
          :latencyChartOptions="latencyChartOptions"
          :loadingLatencyData="loadingLatencyData"
          :handleTimeRangeChange="handleTimeRangeChange"
        />
      </a-spin>
    </a-modal>
  </div>
</template>

<style scoped>
.scheduling-view {
  padding: 24px;
  background: #f5f5f5;
  min-height: 100vh;
}

.header-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 24px;
  padding: 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.toolbar-left h2 {
  margin: 0 0 8px 0;
  color: #262626;
  font-size: 24px;
  font-weight: 600;
}

.toolbar-left .description {
  margin: 0;
  color: #8c8c8c;
  font-size: 14px;
}

.toolbar-right {
  display: flex;
  gap: 12px;
}

.topology-container {
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  position: relative;
  padding: 0;
}

.graph-container {
  width: 100%;
  background: #fafafa;
  border: 1px solid #f0f0f0;
  display: block;
  margin: 0;
  padding: 0;
}

.simple-topology-wrapper {
  width: 100%;
  min-height: 400px;
  padding: 20px;
  background: #fafafa;
  border: 1px solid #f0f0f0;
  border-radius: 4px;
  margin: 0;
}

.operation-tips {
  position: absolute;
  top: 16px;
  right: 16px;
  background: rgba(255, 255, 255, 0.95);
  padding: 12px 16px;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(4px);
}

.selected-node-info {
  position: absolute;
  top: 16px;
  left: 16px;
  background: rgba(255, 255, 255, 0.95);
  padding: 12px 16px;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(4px);
  border-left: 3px solid #1890ff;
  min-width: 200px;
}

.info-header {
  font-size: 14px;
  font-weight: 600;
  color: #262626;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.info-header::before {
  content: "📍";
  font-size: 12px;
}

.info-details {
  font-size: 12px;
  color: #666;
  margin-bottom: 8px;
}

.tip-item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 12px;
  color: #666;
}

.tip-item:last-child {
  margin-bottom: 0;
}

.tip-icon {
  font-size: 14px;
}

.legend {
  margin-top: 24px;
  padding: 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.legend h3 {
  margin: 0 0 16px 0;
  color: #262626;
  font-size: 16px;
  font-weight: 600;
}

.legend-items {
  display: flex;
  gap: 24px;
  flex-wrap: wrap;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #595959;
}

.legend-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid;
}

.master-ready {
  background-color: #52c41a;
  border-color: #1890ff;
}

.master-notready {
  background-color: #ff4d4f;
  border-color: #1890ff;
}

.worker-ready {
  background-color: #1890ff;
  border-color: #52c41a;
}

.worker-notready {
  background-color: #ff4d4f;
  border-color: #52c41a;
}

.latency-modal-content {
  padding: 16px 0;
}

.latency-stats {
  background: #fafafa;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
}

.stats-section {
  margin-bottom: 16px;
}

.stats-section:last-child {
  margin-bottom: 0;
}

.stats-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 16px 0;
  font-size: 15px;
  font-weight: 600;
  color: #262626;
}

.direction-indicator {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 14px;
  font-weight: bold;
  color: white;
}

.direction-indicator.forward {
  background: #1890ff;
}

.direction-indicator.backward {
  background: #52c41a;
}

.chart-container {
  border: 1px solid #f0f0f0;
  border-radius: 8px;
  overflow: hidden;
  background: white;
}

/* 统计数字样式优化 */
:deep(.ant-statistic-title) {
  font-size: 13px;
  color: #8c8c8c;
  margin-bottom: 8px;
}

:deep(.ant-statistic-content) {
  font-weight: 600;
}

/* 分割线样式 */
:deep(.ant-divider-horizontal) {
  border-top-color: #e8e8e8;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .scheduling-view {
    padding: 16px;
  }

  .header-toolbar {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }

  .toolbar-right {
    justify-content: flex-end;
  }

  .legend-items {
    flex-direction: column;
    gap: 12px;
  }

  .operation-tips {
    position: static;
    margin: 16px 16px 0;
  }

  .selected-node-info {
    position: static;
    margin: 16px 0;
    width: auto;
  }
}

/* G6 图形相关样式 */
:deep(.g6-component-tooltip) {
  background: rgba(0, 0, 0, 0.75);
  color: white;
  border-radius: 4px;
  padding: 8px 12px;
  font-size: 12px;
  max-width: 200px;
}

/* 加载动画 */
.ant-spin-nested-loading {
  min-height: 400px;
}

.ant-spin-container {
  min-height: 400px;
  display: block;
  margin: 0;
  padding: 0;
}

:deep(.ant-spin-nested-loading) {
  position: relative;
  margin: 0;
  padding: 0;
}

:deep(.ant-spin-container) {
  transition: opacity 0.3s;
  margin: 0;
  padding: 0;
  display: block;
}

/* 自定义滚动条 */
.topology-container::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.topology-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.topology-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.topology-container::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

.time-range-selector {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  background: #f8f9fa;
  padding: 16px 20px;
  border-radius: 8px;
  border: 1px solid #e9ecef;
}

.selector-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-right: 10px;
}

.selector-icon {
  font-size: 16px;
}

.selector-title {
  font-size: 14px;
  font-weight: 600;
  color: #262626;
}

/* 选择器样式 */
:deep(.ant-select) {
  font-size: 14px;
}

:deep(.ant-select-selector) {
  border-radius: 6px;
  border-color: #d9d9d9;
}

:deep(.ant-select-focused .ant-select-selector) {
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

/* 加载状态样式 */
:deep(.ant-spin-nested-loading) {
  position: relative;
}

:deep(.ant-spin-container) {
  transition: opacity 0.3s;
}

/* 模态框loading样式优化 */
:deep(.ant-modal-body) {
  padding: 24px;
}

:deep(.ant-spin-nested-loading) {
  min-height: 200px;
}

:deep(.ant-spin-spinning) {
  position: relative;
}

:deep(.ant-spin-dot) {
  font-size: 24px;
}

:deep(.ant-spin-text) {
  color: #666;
  font-size: 14px;
  margin-top: 8px;
}
</style>
